#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>

// #define SIZE 1024

// void Usage(std::string proc)
// {
//     std::cout << "\nUsage: " << proc << " serverip serverport\n"
//               << std::endl;
// }

// int main(int argc, char *argv[])
// {
//     if (argc != 3)
//     {
//         Usage(argv[0]);
//         exit(1);
//     }

//     std::string server_ip = argv[1];
//     uint16_t server_port = atoi(argv[2]);

//     int sock = socket(AF_INET, SOCK_STREAM, 0);
//     if (sock < 0)
//     {
//         std::cerr << "client: 创建套接字失败。 socket: " << sock << std::endl;
//         exit(2);
//     }
//     std::cout << "client: 创建套接字成功。 socket: " << sock << std::endl;

//     struct sockaddr_in serveraddr;
//     bzero(&serveraddr, sizeof(serveraddr));
//     serveraddr.sin_family = AF_INET;
//     serveraddr.sin_port = htons(server_port);
//     inet_aton(server_ip.c_str(), &serveraddr.sin_addr);

//     if (connect(sock, (struct sockaddr *)&serveraddr, sizeof serveraddr) < 0)
//     {
//         std::cerr << "client: connect建立连接失败。" << std::endl;
//         exit(3);
//     }
//     std::cout << "client: connect建立连接成功。" << std::endl;

//     while(true)
//     {
//         std::string message;
//         std::cout <<"请输入# ";
//         std::getline(std::cin,message);
//         send(sock,message.c_str(),message.size(),0);


//         char client_buffer[SIZE];
//         ssize_t ret = recv(sock,client_buffer,sizeof(client_buffer)-1,0);
//         if(ret > 0)
//         {
//             client_buffer[ret]=0;
//             std::cout<<"client-服务器响应：" << client_buffer << std::endl;
//         }
//     }

//     return 0;
// }


#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define SIZE 1024


// 使用手册
void Usage(std::string proc)
{
    std::cout << "\nUsage: " << proc << " serverip serverport\n" << std::endl;
}

// 启动方式：udp_client server_ip server_port
int main(int argc, char *argv[])
{
    // 1、获取命令行传入的端口号、IP：注意将其转换为对应的类型
    // a、检测命令行参数是否正确
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }

    // b、获取服务端端口号、IP
    std::string server_ip = argv[1];
    uint16_t server_port = atoi(argv[2]);

    // 2、创建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0)
    {
        std::cerr << "client: 创建套接字失败。 socket: " << sock << std::endl;
        exit(2);
    }

    // 3、客户端需要有连接服务端的能力（PS：客户端不需要bind，一般由OS自动分配端口号）
    // a、准备工作：
    struct sockaddr_in serveraddr;
    bzero(&serveraddr, 0);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(server_port);//端口号：需要进行网络字节序的转换
    serveraddr.sin_addr.s_addr = inet_addr(server_ip.c_str());//IP：
    // b、建立连接
    if(connect(sock, (struct sockaddr*)&serveraddr, sizeof serveraddr) < 0)
    {
        std::cerr << "client: connect建立连接失败。" << std::endl;
        exit(3);
    }
    std::cout << "client: connect建立连接成功。" << std::endl;


    // 4、链接成功，即可通讯
    while(true)
    {
        //a、客户端向服务端发送数据
        std::string message;
        std::cout << "client-请输入# ";
        std::getline(std::cin,message);
        send(sock, message.c_str(), message.size(),0);

        //b、客户端接收服务端传回的数据
        char client_buff[SIZE];
        ssize_t s = recv(sock,client_buff,sizeof(client_buff)-1,0);
        if(s > 0)//成功接收到数据
        {
            client_buff[s] = 0;
            std::cout << "client-服务端响应：" << client_buff << std::endl;
        }
    }


    return 0;
}